﻿using Common.Communication;
using Common.Device.DeviceDb;
using Common.Device.Enums;
using Common.Device.Interfaces;
using Common.Device.Models;
using Common.Device.ViewModels;
using Common.Tool.DataTools;
using Common.Tool.Models;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Xml.Linq;

namespace Common.Device
{
    public class DeviceService
    {
        /// <summary>
        /// 全局停止测试
        /// </summary>
        public static bool IsStop { get; set; }
        /// <summary>
        /// 所有支持的仪器列表
        /// </summary>
        public static List<AllDevice> allDevices => DeviceDbHelper.db.Queryable<AllDevice>().ToList();
        /// <summary>
        /// 当前配置的仪器列表字典，key为仪器标识
        /// </summary>
        public static Dictionary<string, UseDevice> useDevices => DeviceDbHelper.db.Queryable<UseDevice>().ToList().ToDictionary(o => o.name, o => o) ?? new Dictionary<string, UseDevice>();
        /// <summary>
        /// 当前实例化的仪器操作类，key为仪器标识
        /// </summary>
        public static Dictionary<string, object> iDevices { get; set; } = new Dictionary<string, object>();
        /// <summary>
        /// 实例化仪器操作类的工厂方法
        /// </summary>
        /// <param name="device">仪器配置</param>
        /// <param name="document">日志控件类</param>
        /// <returns></returns>
        public static object DeviceFactory(UseDevice device, RichDocument document = null)
        {
            //空则返回
            if (device == null)
            {
                return null;
            }
            //未包含当前仪器时，自动插入数据库
            if (useDevices.ContainsKey(device.name) == false /*|| useDevices[device.name].isSame(device) == false*/)
            {
                device.type = allDevices.FirstOrDefault(it => it.model == device.model).type;
                device.temp = allDevices.FirstOrDefault(it => it.model == device.model).temp;
                device.descripe = allDevices.FirstOrDefault(it => it.model == device.model).descripe;
                DeviceDbHelper.db.Insertable(device).ExecuteCommand();
                device = useDevices[device.name];
            }
            //获取类型
            iDevices.TryGetValue(device.name, out object idevice);
            if (idevice == null)
            {
                string name = "";
                string folder = "";
                try
                {
                    switch (device.model)
                    {
                        //通过仪器型号查找对应程序集
                        case DeviceEnum.DeviceModelEnum.AT686:
                        case DeviceEnum.DeviceModelEnum.EEC7473:
                        case DeviceEnum.DeviceModelEnum.TH2689:
                        case DeviceEnum.DeviceModelEnum.TH9201B:
                            name = "AnGuiYi."; folder = "JueYuanNaiYa."; break;
                        case DeviceEnum.DeviceModelEnum.RSWSN012D:
                            name = "CaiJiMoKuai."; folder = "WenDu."; break;
                        case DeviceEnum.DeviceModelEnum.ZH_4211_14D2_30V:
                            name = "CaiJiMoKuai."; folder = "DianYaCaiJi."; break;
                        case DeviceEnum.DeviceModelEnum.ZH_44081_14M2_10V_20V:
                            name = "CaiJiMoKuai."; folder = "DianYaCaiJi."; break;
                        case DeviceEnum.DeviceModelEnum.ZH_42141_14N2_10V:
                            name = "CaiJiMoKuai."; folder = "DianYaCaiJi."; break;
                        case DeviceEnum.DeviceModelEnum.ZH_42241_14N2_5V:
                            name = "CaiJiMoKuai."; folder = "DianYaCaiJi."; break;
                        case DeviceEnum.DeviceModelEnum.ZH_42241_14N2_30V:
                            name = "CaiJiMoKuai."; folder = "DianYaCaiJi."; break;
                        case DeviceEnum.DeviceModelEnum.ZH_44121_14F2_10V_20V:
                            name = "CaiJiMoKuai."; folder = "DianYaCaiJi."; break;
                        case DeviceEnum.DeviceModelEnum.ZH_44241_14F2_30V:
                            name = "CaiJiMoKuai."; folder = "DianYaCaiJi."; break;
                        case DeviceEnum.DeviceModelEnum.ZH_42241_14F2_10V:
                            name = "CaiJiMoKuai."; folder = "DianYaCaiJi."; break;
                        case DeviceEnum.DeviceModelEnum.AT512:
                            name = "CeLiangYi."; folder = "DianZuYi."; break;
                        case DeviceEnum.DeviceModelEnum.UTR2830E:
                            name = "CeLiangYi."; folder = "ShuZiDianQiao."; break;
                        case DeviceEnum.DeviceModelEnum.DM3058E:
                            name = "CeLiangYi."; folder = "WanYongBiao."; break;
                        case DeviceEnum.DeviceModelEnum.AC11005:
                        case DeviceEnum.DeviceModelEnum.AC13003:
                            name = "DianYuan."; folder = "AC."; break;
                        case DeviceEnum.DeviceModelEnum.IT6722A:
                        case DeviceEnum.DeviceModelEnum.UDP3305S_E:
                        case DeviceEnum.DeviceModelEnum.DP811:
                            name = "DianYuan."; folder = "DC."; break;
                        case DeviceEnum.DeviceModelEnum.IT8511:
                        case DeviceEnum.DeviceModelEnum.IT8813:
                            name = "DianZiFuZai."; folder = ""; break;
                        case DeviceEnum.DeviceModelEnum.DHO1202:
                            name = "ShiBoQi."; folder = ""; break;
                        case DeviceEnum.DeviceModelEnum.FctModBus:
                        case DeviceEnum.DeviceModelEnum.FctModBus3:
                            name = "Fct."; folder = ""; break;
                        case DeviceEnum.DeviceModelEnum.RS232:
                        case DeviceEnum.DeviceModelEnum.TcpClient:
                            name = "TongXin."; folder = ""; break;
                        case DeviceEnum.DeviceModelEnum.N110C:
                            name = "GeChaoJi."; folder = ""; break;
                        case DeviceEnum.DeviceModelEnum.N110Z:
                            name = "ZhiKong."; folder = ""; break;
                        default:
                            break;
                    }
                    //动态加载程序集
                    Assembly loadedAssembly = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + name + "dll");
                }
                catch (Exception)
                {
                    return null;
                }
                //获取命名空间

                string className = device.model.ToString();
                if (device.type==Enums.DeviceEnum.DeviceTypeEnum.电压采集)
                {
                    className="ZhongChuangZhiHe";
                }
                switch (device.mode)
                {
                    case Enums.DeviceEnum.DeviceModeEnum.RS232:
                        className += "SerialPort";
                        break;
                    case Enums.DeviceEnum.DeviceModeEnum.RS485:
                        className += "SerialPort";
                        break;
                    case Enums.DeviceEnum.DeviceModeEnum.USB_NI:
                        className += "NiVisa";
                        break;
                    case Enums.DeviceEnum.DeviceModeEnum.TCP_Client:
                        className += "SocketClient";
                        break;
                    default:
                        break;
                }
                // 获取当前程序集
                Assembly assembly = AppDomain.CurrentDomain.GetAssemblies()
                                   .FirstOrDefault(asm => asm.GetName().Name == name.Substring(0, name.Length - 1));
                if (assembly == null)
                {
                    return null;
                }
                // 获取类型
                Type type = assembly.GetType(name + folder + className);
                if (type == null)
                {
                    return null;
                }
                // 准备传递给构造函数的参数
                object[] constructorArgs = new object[] { device };
                // 使用带参数的构造函数实例化对象
                idevice = Activator.CreateInstance(type, constructorArgs);
                iDevices.Add(device.name, idevice);
            }
            if (idevice != null && document != null)
            {
                //传入日志类
                (idevice as IDevice).document = document;
            }
            return idevice;
        }
        /// <summary>
        /// 通用仪器测试方法
        /// </summary>
        /// <param name="device">仪器参数数据库对象</param>
        /// <param name="order">测试指令</param>
        /// <param name="testOrder">测试项</param>
        /// <returns></returns>
        public static DeviceResult DeviceTest(UseDevice device, Order order, TestOrder testOrder)
        {
            //函数模块判断
            if (device == null && Enum.GetNames(typeof(FuncEnum.TestMode)).ToList().Contains(order.temp))
            {
                //函数模块
                var deviceModel = JsonConvert.DeserializeObject<Func>(order.deviceModel);
                deviceModel.mode = (FuncEnum.TestMode)Enum.Parse(typeof(FuncEnum.TestMode), order.temp);
                return deviceModel.GetResult(null,testOrder); 
            }
            var idevice = DeviceFactory(device,testOrder.document);
            if (idevice is IJueYuanNaiYa)
            {
                //绝缘耐压
                var deviceModel = JsonConvert.DeserializeObject<JueYuanNaiYa>(order.deviceModel);
                deviceModel.mode = (AnGuiYiEnum.TestMode)Enum.Parse(typeof(AnGuiYiEnum.TestMode), order.temp);
                return deviceModel.GetResult(idevice, testOrder);
            }
            if (idevice is ICaiJiMoKuai)
            {
                //采集模块
                var deviceModel = JsonConvert.DeserializeObject<CaiJiMoKuai>(order.deviceModel);
                deviceModel.mode = (CaiJiMoKuaiEnum.TestMode)Enum.Parse(typeof(CaiJiMoKuaiEnum.TestMode), order.temp);
                return deviceModel.GetResult(idevice, testOrder);
            }
            if (idevice is IDianYaCaiJi)
            {
                //采集模块
                var deviceModel = JsonConvert.DeserializeObject<DianYaCaiJi>(order.deviceModel);
                deviceModel.mode = (DianYaCaiJiEnum.TestMode)Enum.Parse(typeof(DianYaCaiJiEnum.TestMode), order.temp);
                return deviceModel.GetResult(idevice, testOrder);
            }
            if (idevice is IWanYongBiao||idevice is IDianZuYi||idevice is IShuZiDianQiao)
            {
                //测量仪
                var deviceModel = JsonConvert.DeserializeObject<CeLiangYi>(order.deviceModel);
                deviceModel.mode = (CeLiangYiEnum.TestMode)Enum.Parse(typeof(CeLiangYiEnum.TestMode), order.temp);
                return deviceModel.GetResult(idevice, testOrder);
            }
            if (idevice is IDianYuan)
            {
                //电源
                var deviceModel = JsonConvert.DeserializeObject<DianYuan>(order.deviceModel);
                deviceModel.mode = (DianYuanEnum.TestMode)Enum.Parse(typeof(DianYuanEnum.TestMode), order.temp);
                return deviceModel.GetResult(idevice, testOrder);
            }
            if (idevice is IDianZiFuZai)
            {
                //电子负载
                var deviceModel = JsonConvert.DeserializeObject<DianZiFuZai>(order.deviceModel);
                deviceModel.mode = (DianZiFuZaiEnum.TestMode)Enum.Parse(typeof(DianZiFuZaiEnum.TestMode), order.temp);
                return deviceModel.GetResult(idevice, testOrder);
            }
            if (idevice is IShiBoQi)
            {
                //示波器
                var deviceModel = JsonConvert.DeserializeObject<ShiBoQi>(order.deviceModel);
                deviceModel.mode = (ShiBoQiEnum.TestMode)Enum.Parse(typeof(ShiBoQiEnum.TestMode), order.temp);
                return deviceModel.GetResult(idevice, testOrder);
            }
            if (idevice is IFct||idevice is IFct3)
            {
                //测试板卡
                var deviceModel = JsonConvert.DeserializeObject<Fct>(order.deviceModel);
                deviceModel.mode = (FctEnum.TestMode)Enum.Parse(typeof(FctEnum.TestMode), order.temp);
                return deviceModel.GetResult(idevice, testOrder);
            }
            if (idevice is ITongXin)
            {
                //通信功能
                var deviceModel = JsonConvert.DeserializeObject<TongXin>(order.deviceModel);
                deviceModel.mode = (TongXinEnum.TestMode)Enum.Parse(typeof(TongXinEnum.TestMode), order.temp);
                return deviceModel.GetResult(idevice, testOrder);
            }
            if (idevice is IGeChaoJi)
            {
                //割草机
                var deviceModel = JsonConvert.DeserializeObject<GeChaoJi>(order.deviceModel);
                deviceModel.mode = (GeChaoJiEnum.TestMode)Enum.Parse(typeof(GeChaoJiEnum.TestMode), order.temp);
                return deviceModel.GetResult(idevice, testOrder);
            }
            if (idevice is IZhiKong)
            {
                //割草机
                var deviceModel = JsonConvert.DeserializeObject<ZhiKong>(order.deviceModel);
                deviceModel.mode = (ZhiKongEnum.TestMode)Enum.Parse(typeof(ZhiKongEnum.TestMode), order.temp);
                return deviceModel.GetResult(idevice, testOrder);
            }
            return new DeviceResult();
        }
    }
}
